package com.mdd.generator.test;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Collections;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

public class DeepSeekAPI {
	
	// 无prefix
//    final static String DEEPSEEK_URL = "https://api.deepseek.com/chat/completions";
    // 有prefix
    final static String DEEPSEEK_URL = "https://api.deepseek.com/beta/chat/completions";
    
    final static String API_KEY = "sk-62ccf0ee37a744e086dd1e0bd0f2f3a5";
    
    final static String PROMPT = "川菜馆用餐体验评价\\n\" +\n" +
            "\"\\n\" +\n" +
            "\"请根据您的真实体验填写以下内容（🌟可替换为具体描述）：\\n\" +\n" +
            "\"\\n\" +\n" +
            "\"---\\n\" +\n" +
            "\"\\n\" +\n" +
            "\" 🏮 环境氛围\\n\" +\n" +
            "\"	装修风格：  \\n\" +\n" +
            "\"	卫生状况： (桌面/地面/餐具清洁度)  \\n\" +\n" +
            "\"	舒适度： (座位间距/灯光/温度/噪音程度)  \\n\" +\n" +
            "\"	特色氛围： (是否体现川渝特色/背景音乐/空间布局)  \\n\" +\n" +
            "\n" +
            "\" 💁 服务态度\\n\" +\n" +
            "\"	响应速度： (点餐/加水/结账效率)  \\n\" +\n" +
            "\"	友好专业： (服务员是否热情/耐心解答问题/主动服务意识)  \\n\" +\n" +
            "\"	问题处理： (对菜品反馈或特殊需求的应对)  \\n\" +\n" +
            "\"	其他服务： (是否主动介绍菜品/推荐/提供围裙等)  \\n\" +\n" +
            "\n" +
            "\" 🥢 菜品体验\\n\" +\n" +
            "\"	招牌/必点菜： (请列出菜名及评价)  \\n\" +\n" +
            "\"	口味正宗度： (是否符合您对川菜的预期)  \\n\" +\n" +
            "\"	辣度把控： (可选辣度是否清晰/实际辣度与选择是否匹配)  \\n\" +\n" +
            "\"	食材新鲜度：  \\n\" +\n" +
            "\"	菜品创新： (是否有特色融合菜或独特做法)  \\n\" +\n" +
            "\"	份量与价格： (性价比如何)  \\n\" +\n" +
            "\"	改进建议： (哪些菜有提升空间？)  \\n\" +\n" +
            "\n" +
            "\" 🚗 交通与便利性\\n\" +\n" +
            "\"	地理位置： (是否好找/周边地标)  \\n\" +\n" +
            "\"	公共交通： (地铁/公交站距离及便利度)  \\n\" +\n" +
            "\"	停车便利： (是否有停车场/收费情况/车位紧张度)  \\n\" +\n" +
            "\n" +
            "\"---\\n\" +\n" +
            "\"\\n\" +\n" +
            "\"📌 您最推荐的一道菜是什么？为什么？\\n\" +\n" +
            "\"> (您的回答)  \\n\" + \n" +
            "\"\\n\" +\n" +
            "\"📌 您会再次光顾或推荐给朋友吗？\\n\" +\n" +
            "\"> (您的回答)  \\n\" + \n" +
            "\"\\n\" +\n" +
            "\"📌 您是如何前往餐馆的，交通是否便利？\\n\" +\n" +
            "\"> (您的回答)  \\n\" + \n" +
            "\"\\n\" +\n" +
            "\"📌 其他补充或难忘细节：  \\n\" +\n" +
            "\"> (您的回答)  \\n\" + \n" +
            "\"📌 总体评分： (例如：⭐️⭐️⭐️⭐️⭐️)  \\n\" +\n" +
            "\"\\n\" +\n";

    public static void main(String[] args) {
    	String userInputMsg = "请写一段菜品评价";
        nonSSE(userInputMsg);
//    	sse(userInputMsg);
    }

    /**
     * 非流式生成
     * @return 
     * 🏮 环境氛围  
		装修风格：现代简约风，融入川剧脸谱元素  
		卫生状况：桌面整洁，地面无油渍，餐具消毒到位  
		舒适度：座位间距适中，灯光柔和，空调温度适宜，背景音乐音量刚好  
		特色氛围：红灯笼装饰和竹编吊灯营造出川渝风情  
		
		💁 服务态度  
		响应速度：扫码点餐后10分钟内上齐菜品，加水及时  
		友好专业：服务员主动介绍招牌菜，提醒辣度选择  
		问题处理：对"少油"需求调整迅速，赠送解辣冰粉  
		其他服务：提供一次性围裙和手机密封袋  
		
		🥢 菜品体验  
		招牌菜：沸腾鱼（鱼肉嫩滑/麻香四溢）毛血旺（鸭血新鲜/配料丰富）  
		口味正宗度：麻椒使用地道，还原成都本地风味  
		辣度把控：可选微辣/中辣/特辣，实际辣度与选择一致  
		食材新鲜度：蔬菜脆嫩，肉类无腥味  
		菜品创新：藤椒美蛙配酸奶冰粉很有创意  
		份量与价格：人均80元，3人套餐足够4人食用  
		改进建议：夫妻肺片可增加牛舌比例  
		
		🚗 交通与便利性  
		地理位置：商场4楼餐饮区，近电影院  
		公共交通：地铁3号线直达，B出口步行5分钟  
		停车便利：商场地下停车场，消费满200免2小时  
		
		📌 最推荐沸腾鱼：活鱼现杀，青花椒香气穿透力强，底层豆芽入味  
		📌 会再次光顾：每月推出时令新菜，服务细致周到  
		📌 交通方式：地铁前往，出口直达商场非常方便  
		📌 难忘细节：等位时提供免费四川小吃拼盘  
		总体评分：⭐️⭐️⭐️⭐️⭐
     */
    public static String nonSSE(String inputMsg) {
    	ObjectMapper mapper = new ObjectMapper();
        ObjectNode request = mapper.createObjectNode();
        request.put("model", "deepseek-chat");
        request.put("stream", false);
        
        ArrayNode messages = mapper.createArrayNode();
        // system
        ObjectNode systemMsg = mapper.createObjectNode();
        systemMsg.put("role", "system");
        systemMsg.put("content", PROMPT + "根据以上提示词，只需给出每个问题的结果即可。");
        messages.add(systemMsg);
        // user
        ObjectNode userMsg = mapper.createObjectNode();
        userMsg.put("role", "user");
        userMsg.put("content", inputMsg);
        messages.add(userMsg);
        // assistant
        ObjectNode assistantMsg = mapper.createObjectNode();
        assistantMsg.put("role", "assistant");
        assistantMsg.put("content", "```markdown\n");
        assistantMsg.put("prefix", true);
        messages.add(assistantMsg);
        request.set("messages", messages);
        request.put("stop", "```");
        
    	RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.setBearerAuth(API_KEY);
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
    	try {
            HttpEntity<String> entity = new HttpEntity<>(mapper.writeValueAsString(request), headers);
            ResponseEntity<String> response = restTemplate.exchange(DEEPSEEK_URL, HttpMethod.POST, entity, String.class);
            if (response.getStatusCode() == HttpStatus.OK) {
                JsonNode jsonNode = mapper.readTree(response.getBody());
                String content = jsonNode.at("/choices/0/message/content").asText();
                System.out.println("Generated Content:\n" + content);
                return content;
            }

            System.err.println("API Error: " + response.getStatusCode());
            System.err.println("Response: " + response.getBody());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 流式生成
     * @return 同上返回结果 {@link nonSSE()}
     */
    public static SseEmitter sse(String inputMsg) {
        SseEmitter emitter = new SseEmitter(0L);
        new Thread(() -> {
            try {
            	sendStreamChat(emitter, inputMsg);
            } catch (Exception e) {
                emitter.completeWithError(e);
            }
        }).start();
        return emitter;
    }
    
    private static void sendStreamChat(SseEmitter emitter, String inputMsg) throws Exception {
    	ObjectMapper mapper = new ObjectMapper();
        ObjectNode request = mapper.createObjectNode();
        request.put("model", "deepseek-chat");
        request.put("stream", true);
        // system
        ArrayNode messages = mapper.createArrayNode();
        ObjectNode systemMsg = mapper.createObjectNode();
        systemMsg.put("role", "system");
        systemMsg.put("content", PROMPT + "根据以上提示词，只需给出每个问题的结果即可。");
        messages.add(systemMsg);
        // user
        ObjectNode userMsg = mapper.createObjectNode();
        userMsg.put("role", "user");
        userMsg.put("content", inputMsg);
        messages.add(userMsg);

        request.set("messages", messages);

        URL url = new URL(DEEPSEEK_URL);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
        conn.setRequestProperty("Authorization", "Bearer " + API_KEY);
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setRequestProperty("Accept", "text/event-stream");

        try (OutputStream os = conn.getOutputStream()) {
            os.write(mapper.writeValueAsBytes(request));
            os.flush();
        }

        try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
            String line;
            StringBuilder full = new StringBuilder();
            while ((line = reader.readLine()) != null) {
                if (line.startsWith("data: ")) {
                    String data = line.substring(6).trim();
                    if ("[DONE]".equals(data)) {
                        break;
                    }

                    JsonNode node = mapper.readTree(data);
                    String content = node.at("/choices/0/delta/content").asText("");
                    System.out.println("Generate Content:" + content);
                    full.append(content);
                    emitter.send(SseEmitter.event().data(content));
                }
            }
            System.out.println("Generate Full Content:" + full);
            emitter.complete();
        } catch (Exception e) {
            emitter.completeWithError(e);
            throw e;
        } finally {
            conn.disconnect();
        }
    }
}
